﻿using System;
using System.Net.Mail;
using System.Text;
using System.Threading;
using System.Windows;
using System.Windows.Media.Imaging;
using Automator.Tasks.Core;
using Automator.Tasks.Windows;

namespace Automator.Tasks
{
    /// <summary>
    /// Class that compares WorkflowExecutionContext.Result with user-defined value
    /// Defined attributes:
    /// EstimatedResult: Value for comparison
    /// </summary>
    public class SendMailTask: Task, ITaskExecutable
    {
        /// <summary>
        /// Field for catch an exception in a thread
        /// </summary>
        private static Exception ThreadException;
        
        /// <summary>
        /// Sync object
        /// </summary>
        private static object locker = new object();
        
        public void Execute(WorkflowExecutionContext context)
        {
            Thread t = new Thread(new ParameterizedThreadStart(SendAMail));
            t.Start(new TaskThreadingContext(this, context));
            t.Join();
            if (ThreadException != null)
                throw new TaskExecutionException(ThreadException.Message, ThreadException);
        }
        
        public SendMailTask():
            base()
        {
            this.Title = "Send Mail";
            this.Description = "Send mail message";
            this.TaskImage = new BitmapImage(new Uri("/Automator.Tasks.Net;component/Resources/email.png", UriKind.Relative));
            
            this.Attributes.Add(new TaskAttributeDefinition() { Key="AddressFrom", Value = String.Empty });
            this.Attributes.Add(new TaskAttributeDefinition() { Key="AddressTo", Value = String.Empty });
            this.Attributes.Add(new TaskAttributeDefinition() { Key="Subject", Value = String.Empty });
            this.Attributes.Add(new TaskAttributeDefinition() { Key="Body", Value = String.Empty });
            this.Attributes.Add(new TaskAttributeDefinition() { Key="Host", Value = String.Empty });
            this.Attributes.Add(new TaskAttributeDefinition() { Key="Port", Value = String.Empty });
        }
        
        public override string CommandText
        {
            get { return this.Attributes["Subject"].Value.ToString().Trim(); }
            set { base.CommandText = value; }
        }
        
        public override bool EditTask()
        {
            base.EditTask();
            SendMailTaskEditWindow window = new SendMailTaskEditWindow();
            window.Owner = Application.Current.MainWindow;
            window.Title = String.Format("Edit {0} Task", this.Title);
            //performing binding to the header
            window.header.ContentPanel.DataContext = this;

            window.edtHost.Text = this.Attributes["Host"].Value.ToString();
            window.edtPort.Text = this.Attributes["Port"].Value.ToString();
            window.edtFrom.Text = this.Attributes["AddressFrom"].Value.ToString();
            window.edtTo.Text = this.Attributes["AddressTo"].Value.ToString();
            window.edtSubj.Text = this.Attributes["Subject"].Value.ToString();
            window.edtBody.Text = this.Attributes["Body"].Value.ToString();
            window.footer.BtnOK.Click += delegate { window.DialogResult = true; };

            if (window.ShowDialog() == true)
            {
                this.Attributes["Host"].Value = window.edtHost.Text.Trim();
                this.Attributes["Port"].Value = window.edtPort.Text.Trim();
                this.Attributes["AddressFrom"].Value = window.edtFrom.Text.Trim();
                this.Attributes["AddressTo"].Value = window.edtTo.Text.Trim();
                this.Attributes["Subject"].Value = window.edtSubj.Text.Trim();
                this.Attributes["Body"].Value = window.edtBody.Text.Trim();
                
                this.CommandText = String.Empty;
                return true;
            }
            else return false;
        }
        
        private void SendAMail(object arg)
        {
            lock(locker)
            {
                try
                {
                    SendMailTask task = (SendMailTask)(arg as TaskThreadingContext).Task;
                    WorkflowExecutionContext context = (arg as TaskThreadingContext).ExecutionContext;
                    using (SmtpClient client = new SmtpClient(
                        context.DereferenceVariables(task.Attributes["Host"].Value),
                        Convert.ToInt32(context.DereferenceVariables(task.Attributes["Port"].Value))
                       ))
                    {
                        MailMessage message = new MailMessage(
                            context.DereferenceVariables(task.Attributes["AddressFrom"].Value),
                            context.DereferenceVariables(task.Attributes["AddressTo"].Value),
                            context.DereferenceVariables(task.Attributes["Subject"].Value),
                            context.DereferenceVariables(task.Attributes["Body"].Value)
                           );                        
                        Encoding utf8 = Encoding.UTF8;
                        message.BodyEncoding = utf8;
                        message.HeadersEncoding = utf8;
                        message.SubjectEncoding = utf8;
                        message.IsBodyHtml = true;
                        
                        client.UseDefaultCredentials = true;
                        client.Send(message);
                        ThreadException = null;
                    }
                }
                catch (Exception ex)
                {
                    ThreadException = ex;
                }
            }
        }
    }
}